import { useMatchMedia, useSearchParam } from "shared/hooks";
import {
  Select as ISelect,
  SelectItem as ISelectItem,
  SelectProps as ISelectProps,
  SelectItemProps as ISelectItemProps,
  Tooltip,
} from "shared/components";
import { clsxm } from "shared/helpers";
import { ReactNode, useState } from "react";
import { useAtom, useAtomValue, useSetAtom } from "jotai";
import { AnimatePresence, m } from "framer-motion";
import { allYearsAtom, selectYearAtom } from "@/store/years";
import { selectModelAtom, allModelsAtom } from "@/store/model";
import { PromptPopover } from "./PromptPopover";
import { defaultPerson, defaultUri } from "@/lib/constants";
import event from "@/lib/event";
import YearIcon from "@/assets/icons/year.svg?jsx";
import CaretDownIcon from "@/assets/icons/caret-down.svg?jsx";
import SearchIcon from "@/assets/icons/search.svg?jsx";
import MenuIcon from "@/assets/icons/menu.svg?jsx";
import SwitchPersonIcon from "@/assets/icons/switch-person.svg?jsx";
import { switchPersonModalVisibleAtom } from "@/store/switchPerson";

export default function Header() {
  const name = useSearchParam("name", defaultPerson);
  const uri = useSearchParam("uri", defaultUri);
  const isMobile = useMatchMedia("(max-width: 768px)");
  const setSwitchPersonModalVisible = useSetAtom(switchPersonModalVisibleAtom);

  const [showMobileMenu, setShowMobileMenu] = useState(false);

  const heroHomePage = `https://names.library.sh.cn/mrgf/service/work/persons?dataType=1&uri=${uri}`;

  return (
    <header className="relative flex h-[60px] items-center bg-[#4C9571] px-5">
      <Tooltip
        content="切换人物"
        contentClassName="text-xs"
        placement="right"
        placementOffset={10}
      >
        <button
          className="mr-4"
          onClick={() => setSwitchPersonModalVisible((p) => !p)}
        >
          <SwitchPersonIcon />
        </button>
      </Tooltip>
      <a
        className="flex items-center self-stretch"
        href={heroHomePage}
        target="_blank"
      >
        <YearIcon className="text-[#FFD028]" />
        <span className="ml-2 font-[HYMingChanKeBen] text-2xl leading-6 text-white">
          {name}年谱
        </span>
      </a>
      {!isMobile ? (
        <>
          <YearSelector className="ml-auto" />
          <ModelSelector className="ml-4" />

          <button
            className="ml-4 rounded bg-[#256B49] p-2.5 text-white"
            onClick={() => event.emit("load")}
          >
            <SearchIcon height={16} width={16} />
          </button>
          <PromptPopover />
        </>
      ) : (
        <button
          className="ml-auto text-white"
          onClick={() => setShowMobileMenu(!showMobileMenu)}
        >
          <MenuIcon height={32} width={32} />
        </button>
      )}
      {isMobile && (
        <AnimatePresence>
          {showMobileMenu && (
            <>
              <div
                className="fixed inset-0 z-40"
                onClick={() => setShowMobileMenu(false)}
              />
              <m.div
                initial={{ height: 0 }}
                animate={{ height: "auto" }}
                exit={{ height: 0 }}
                className="absolute inset-x-0 top-[60px] z-50 overflow-hidden bg-[#4C9571]"
              >
                <div className="flex flex-col items-stretch gap-y-6 px-8 py-10">
                  <YearSelector onChange={() => setShowMobileMenu(false)} />
                  <ModelSelector />
                  <div className="text-center">
                    <button
                      className="rounded bg-[#256B49] px-10 py-2.5 text-white"
                      onClick={() => {
                        event.emit("load");
                        setShowMobileMenu(false);
                      }}
                    >
                      <SearchIcon height={16} width={16} />
                    </button>
                    <PromptPopover />
                  </div>
                </div>
              </m.div>
            </>
          )}
        </AnimatePresence>
      )}
    </header>
  );
}

function YearSelector({
  className,
  onChange,
}: {
  className?: string;
  onChange?: () => void;
}) {
  const allYears = useAtomValue(allYearsAtom);
  const [year, setYear] = useAtom(selectYearAtom);
  return (
    <Select
      className={className}
      title="时间："
      value={year}
      onChange={(value) => {
        event.emit("scrollYearIntoView", value);
        setYear(value);
        onChange();
      }}
      renderValue={(value) => value.toString()}
    >
      {allYears.map((year) => (
        <SelectItem key={year.raw} label={year.raw} value={year.raw} />
      ))}
    </Select>
  );
}

function ModelSelector({ className }: { className?: string }) {
  const allModels = useAtomValue(allModelsAtom);
  const [model, setModel] = useAtom(selectModelAtom);
  return (
    <Select
      className={className}
      title="模型："
      value={model}
      onChange={setModel}
    >
      {allModels.map((model) => (
        <SelectItem key={model} label={model} value={model} />
      ))}
    </Select>
  );
}

type SelectProps<T> = Omit<
  ISelectProps<T>,
  "renderTrigger" | "contentClassName" | "focusClassName"
> & {
  title: string;
  renderValue?: (value: T) => ReactNode;
};
function Select<T>(props: SelectProps<T>) {
  const {
    children,
    onChange,
    value,
    title,
    className,
    renderValue = (v) => v as ReactNode,
    ...rest
  } = props;

  return (
    <ISelect
      value={value}
      onChange={onChange}
      renderTrigger={(value) => (
        <SelectTrigger renderValue={renderValue} title={title} value={value} />
      )}
      className={clsxm("border-none bg-[#256B49] px-4 py-2", className)}
      contentClassName="overflow-auto"
      {...rest}
    >
      {children}
    </ISelect>
  );
}

type SelectItemProps<T> = ISelectItemProps<T>;
function SelectItem<T>(props: SelectItemProps<T>) {
  const { className, activeClassName, selectedClassName, ...rest } = props;
  return (
    <ISelectItem
      className=""
      activeClassName=""
      selectedClassName=""
      {...rest}
    />
  );
}

type SelectTriggerProps<T> = {
  value: T;
  title: string;
  renderValue: (value: T) => ReactNode;
};
function SelectTrigger<T>(props: SelectTriggerProps<T>) {
  const { title, value, renderValue } = props;
  return (
    <div className="flex text-sm text-white">
      <span className="flex-none">{title}</span>
      <span className="flex-auto pr-4 text-[#C5CBE0]">
        {renderValue(value)}
      </span>
      <span className="flex flex-none items-center">
        <CaretDownIcon />
      </span>
    </div>
  );
}
